#include <vector>
#include <iostream>
#include <cassert>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <functional>
#include <memory>
#include <thread>
#include <mutex>

#include <sys/eventfd.h>
#include <sys/timerfd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
// 这里外部数据拷贝到内部数据主要用copy方法，这个方法就要获取被拷贝前数据的地址，数据拷贝到哪里的地址，所有内部buffer要提供当前的写，读实际地址

#define MUDUO_BUFFER 4096

#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL DBG
static int log = 0;

#define LOG(level, format, ...)                                                                                                  \
    do                                                                                                                           \
    {                                                                                                                            \
        if (level < LOG_LEVEL)                                                                                                   \
            break;                                                                                                               \
        time_t t = time(NULL);                                                                                                   \
        struct tm *ltm = localtime(&t);                                                                                          \
        char tmp[32] = {0};                                                                                                      \
        strftime(tmp, 31, "%Y-%m-%d %H:%M:%S", ltm);                                                                             \
        log++;                                                                                                                   \
        fprintf(stdout, "[%04d %p %s %s:%d] " format "\n", log, (void *)pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

// "ss: %s" -》将##__VA_ARGS__按照format "\n"格式输出     输出到输出流就是ss:字符串这种格式    格式化输出到输出流中
// 前面的一直到"n"表示格式化输出的格式
#define INF_LOG(format, ...) LOG(INF, format, ##__VA_ARGS__)
#define DBG_LOG(format, ...) LOG(DBG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LOG(ERR, format, ##__VA_ARGS__)
// 这个宏接受三个参数：日志级别（level）、日志格式（format）和可变参数列表（__VA_ARGS__）

namespace muduo
{
    class Buffer
    {
    public:
        Buffer() : _buffer(MUDUO_BUFFER), _readr_index(0), _writer_index(0)
        {
        }
        char *readPosition() // 当前读位置
        {
            char *pos = &(*_buffer.begin());
            return (pos + _readr_index);
        }

        char *writePosition() // 当前写位置
        {
            char *pos = &(*_buffer.begin());
            return (pos + _writer_index);
        }

        // 获取缓冲区末尾空闲空间大小--写偏移之后的空闲空间, 总体空间大小减去写偏移
        u_int64_t getBufferTailSize() { return _buffer.size() - _writer_index; }

        // 获取缓冲区起始空闲空间大小--读偏移之前的空闲空间
        u_int64_t getBufferHeadSize() { return _readr_index; }
        // 获取当前缓冲区无效数据区域
        u_int64_t getAllBufferFreeSize() { return getBufferHeadSize() + getBufferTailSize(); }

        // 获取可读数据大小 = 写偏移 - 读偏移
        u_int64_t ReadAbleSize() { return _writer_index - _readr_index; }

        // 将读偏移向后移动
        /*void MoveReadOffset(u_int64_t len)
        {
            _readr_index += len;
            return;
        }*/
        void MoveReadOffset(u_int64_t len)
        {
            if (len == 0)
                return;
            // 向后移动的大小，必须小于可读数据大小
            assert(len <= ReadAbleSize());
            _readr_index += len;
        }

        // 将写偏移向后移动
        void MoveWriteOffset(u_int64_t len)
        {
            // 这里规定如果直接MoveWriteOffset，如果len大于后置空闲空间就返回，只有在EnsureWriteSpace中才进行扩容操作
            if (len == 0)
                return;
            assert(len <= getBufferTailSize());
            _writer_index += len;
            return;
        }

        // 确保可写空间足够（整体空闲空间够了就移动数据，否则就扩容）
        void EnsureWriteSpace(u_int64_t len)
        {
            if (len <= getBufferTailSize())
                return;
            if (len <= getAllBufferFreeSize())
            {
                u_int64_t rsz = ReadAbleSize(); // 可读数据大小
                std::copy(readPosition(), readPosition() + rsz, (char *)(&*_buffer.begin()));
                _readr_index = 0;
                _writer_index = _readr_index + rsz;
            }
            else
            {
                // 此时需要扩容,库容的大小，需要为
                _buffer.resize(len * 2 + _buffer.size());
                _writer_index += len;
            }
        }
        // 数据进行写入
        void Write(const void *data, u_int64_t len)
        {
            EnsureWriteSpace(len);                                                    // 先确保数据可以写入
            std::copy((const char *)data, (const char *)data + len, writePosition()); // 将data中数据拷贝到指定的写位置
        }

        void WriteAndPush(const void *data, u_int64_t len)
        {
            Write(data, len);
            MoveWriteOffset(len);
        }

        void WriteString(const std::string &str)
        {
            Write(str.c_str(), str.size());
        }

        void WriteStringAndPush(const std::string &str)
        {
            WriteAndPush(str.c_str(), str.size());
        }

        void WriteBuffer(Buffer &buffer)
        {
            Write(buffer.readPosition(), buffer.getAllBufferFreeSize());
        }

        void WriteBufferAndPush(Buffer &buffer)
        {
            WriteAndPush(buffer.readPosition(), buffer.getAllBufferFreeSize());
        }

        void Read(void *buf, u_int64_t len) // const &是输入   &是输入输出   *是输出
        {
            // 将指定长度的内容读到传入的缓冲区中，读入指定len字节
            if (len == 0)
                return;
            assert(len <= ReadAbleSize());
            std::copy(readPosition(), readPosition() + len, (char *)buf); // 直接将数据拷贝到buf中
            return;
        }

        void ReadAndPop(void *buf, u_int64_t len)
        {
            Read(buf, len);
            MoveReadOffset(len);
        }

        std::string ReadAsString(u_int64_t len)
        {
            assert(len <= ReadAbleSize());
            std::string str;
            str.resize(len);
            Read((void *)str.c_str(), len);
            return str;
        }

        std::string ReadAsStringAndPop(u_int64_t len)
        {
            assert(len <= ReadAbleSize());
            std::string str;
            str.resize(len);
            ReadAndPop((void *)str.c_str(), len);
            return str;
        }

        char *FindCRLF()
        {
            // 这里"\r\n"查找到'\n'就够了
            void *pos = memchr(readPosition(), '\n', ReadAbleSize());
            if ((char *)pos == nullptr)
                return nullptr;
            return (char *)pos;
        }

        std::string GetLine()
        {
            char *pos = FindCRLF();
            if (pos == nullptr)
                return std::string("");
            return ReadAsString(pos - readPosition() + 1);
        }

        std::string GetLineAndPop()
        {
            char *pos = FindCRLF();
            if (pos == nullptr)
                return std::string("");
            return ReadAsStringAndPop(pos - readPosition() + 1);
        }

        bool ifSatisfyint32_t()
        {
            int size = ReadAbleSize();
            if (size == 32)
                return true;
            else
                return false;
        }

        void clear()
        {
            _readr_index = 0;
            _writer_index = 0;
        }

        ~Buffer() {}

    private:
        std::vector<char> _buffer;
        u_int64_t _readr_index;  // 还未读取的第一个有效位置
        u_int64_t _writer_index; // 当前写入位置，有效数据是前一个
    };

#define MAX_LISTEN 1024

    /// 这个模型是用来提供套接字以及套接字对应的操作的
    class Socket
    {
    public:
        Socket() : _sockfd(1)
        {
        }
        Socket(int sockfd) : _sockfd(sockfd)
        {
        }
        int Fd() { return _sockfd; }
        // 创建套接字
        bool Create()
        {
            // int socket(int domain, int type, int protocol)
            _sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
            if (_sockfd < 0)
            {
                DBG_LOG("SOCKET ERROR");
                return false;
            }
            return true;
        }
        // 绑定地址信息
        bool Bind(const std::string &ip, u_int16_t port)
        {
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(addr);

            int ret = ::bind(_sockfd, (sockaddr *)(&addr), len);
            if (ret < 0)
            {
                DBG_LOG("BIND ERROR");
                return false;
            }
            return true;
        }
        // 开始监听
        bool Listen(int backlog = MAX_LISTEN)
        {
            // int listen(int backlog)
            int ret = ::listen(_sockfd, MAX_LISTEN);
            if (ret < 0)
            {
                DBG_LOG("LISTEN ERROR");
                return false;
            }
            return true;
        }
        // 向服务器发起连接
        bool Connect(const std::string &ip, u_int16_t port)
        {
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(struct sockaddr_in);
            // int connect(int sockfd, struct sockaddr*addr, socklen_t len);
            DBG_LOG("sockfd: %d", _sockfd);
            int ret = connect(_sockfd, (struct sockaddr *)&addr, len);
            if (ret < 0)
            {
                ERR_LOG("CONNECT: %d", ret);
                ERR_LOG("CONNECT SERVER FAILED!");
                return false;
            }
            return true;
        }
        // 获取新连接
        int Accept()
        {
            // int accept(int sockfd, struct sockaddr *addr, socklen_t *len);
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);

            int sockfd = ::accept(_sockfd, (sockaddr *)(&addr), &len);
            if (sockfd < 0)
            {
                DBG_LOG("Accept ERROR");
                abort();
            }
            return sockfd;
        }
        // 接收数据
        ssize_t Recv(void *buf, size_t len, int flag = 0)
        {
            // ssize_t recv(int sockfd, void *buf, size_t len, int flag);
            ssize_t ret = ::recv(_sockfd, buf, len, flag);
            if (ret <= 0)
            {
                DBG_LOG("ret: %ld", ret);
                if (errno == EINTR || errno == EWOULDBLOCK)
                {
                    return 0;
                }
                else
                {
                    ERR_LOG("RECV FAILED");
                    return -1;
                }
            }
            return ret;
        }
        ssize_t NonBlockRecv(void *buf, size_t len) // 进行非阻塞式读取
        {
            return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT表示非阻塞
        }
        // 发送数据
        ssize_t Send(const void *buf, size_t len, int flag = 0)
        {
            // ssize_t send(int sockfd, void *data, size_t len, int flag);
            ssize_t ret = send(_sockfd, buf, len, flag);
            if (ret < 0)
            {
                if (errno == EAGAIN || errno == EINTR)
                {
                    return 0;
                }
                ERR_LOG("SOCKET SEND FAILED!!");
                return -1;
            }
            return ret; // 实际发送的数据长度
        }
        ssize_t NonBlockSend(void *buf, size_t len)
        {
            return Send(buf, len, MSG_DONTWAIT);
        }
        // 关闭套接字
        void Close()
        {
            ::close(_sockfd); // 关闭套接字
        }
        // 创建一个服务端连接  服务端直接调用这个创建一个监听套接字用来进行通信
        bool CreateServer(u_int16_t port, const std::string &ip = "0.0.0.0", bool block_flag = false)
        {
            // 1. 创建套接字，2. 绑定地址，3. 开始监听，4. 设置非阻塞， 5. 启动地址重用
            if (!Create())
                return false;
            if (!Bind(ip, port))
                return false;
            if (!Listen())
                return false;
            if (block_flag)
                NonBlock();
            ReuseAddress();
            return true;
        }
        // 创建一个客户端连接  客户端直接调用这个创建一个普通网络套接字用来进行通信
        bool CreateClient(u_int16_t port, const std::string &ip)
        {
            // 1. 创建套接字，2.指向连接服务器
            if (!Create())
                return false;
            if (!Connect(ip, port))
                return false;
            return true;
        }
        // 设置套接字选项---开启地址端口重用
        void ReuseAddress()
        {
            // int setsockopt(int fd, int leve, int optname, void *val, int vallen)
            int val = 1;
            setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
            val = 1;
            setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&val, sizeof(int));
        }
        // 设置套接字阻塞属性-- 设置为非阻塞
        void NonBlock()
        {
            // int fcntl(int fd, int cmd, ... /* arg */ );
            int fc = ::fcntl(_sockfd, F_GETFD);
            fc |= O_NONBLOCK;
            ::fcntl(_sockfd, F_SETFD, fc);
        }
        ~Socket()
        {
            if (_sockfd != -1)
                Close();
        }

    private:
        int _sockfd;
    };

    // 这是一个进行事件监控管理的模块
    class EventLoop;
    class Channel
    {
        using EventCallback = std::function<void()>; // 事件回调函数类型
    public:
        Channel(EventLoop *loop, int sockfd) : _loop(loop), _sockfd(sockfd), _events(0), _revents(0) {}

        int Fd() { return _sockfd; }

        u_int32_t Events() { return _events; }

        bool AbleRead() { return _events & EPOLLIN; }
        bool AbleWrite() { return _events & EPOLLOUT; }

        /// EventPool进行一次监控，触发的事件
        void setRevents(u_int32_t revents)
        {
            _revents = revents;
        }
        /// 开启读监控
        void enAbleread()
        {
            _events |= EPOLLIN;
            Update();
            return;
        }
        /// 开启写监控
        void enAblewrite()
        {
            _events |= EPOLLOUT;
            Update();
            return;
        }
        /// 关闭读监控
        void disAbleread()
        {
            _events &= ~EPOLLIN;
            Update();
            return;
        }
        /// 关闭写监控
        void disAblewrite()
        {
            _events &= ~EPOLLOUT;
            Update();
            return;
        }

        /// @brief 关闭所有事件监控
        void removeAllevents()
        {
            _events = 0;
            Update();
            return;
        }

        void Remove();
        void Update();

        void set_read_callback(const EventCallback &cb) { _read_callback = cb; }
        void set_write_callback(const EventCallback &cb) { _write_callback = cb; }
        void set_error_callback(const EventCallback &cb) { _error_callback = cb; }
        void set_close_callback(const EventCallback &cb) { _close_callback = cb; }
        void set_event_callback(const EventCallback &cb) { _event_callback = cb; }

        void HandleEvent()
        {
            uint32_t revents = _revents;
            if ((revents & EPOLLIN) || (revents & EPOLLRDHUP) || (revents & EPOLLPRI))
            {
                if (_event_callback)
                    _event_callback();
                /*不管任何事件，都调用的回调函数*/
                if (_read_callback)
                    _read_callback();
            }
            /*有可能会释放连接的操作事件，一次只处理一个*/
            if (revents & EPOLLOUT)
            {
                if (_event_callback)
                    _event_callback();
                if (_write_callback)
                    _write_callback();
            }
            else if (revents & EPOLLERR)
            {
                if (_event_callback)
                    _event_callback();
                if (_error_callback)
                    _error_callback(); // 一旦出错，就会释放连接，因此要放到前边调用任意回调
            }
            else if (revents & EPOLLHUP)
            {
                if (_event_callback)
                    _event_callback();
                if (_close_callback)
                    _close_callback();
            }
            /// 任何事件都调用该接口_event_callback
        }
        // 事件处理，一旦连接触发了事件，就调用这个函数，自己触发了什么事件如何处理自己决定
        /*void HandleEvent()
        {
            if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
            {
                /*不管任何事件，都调用的回调函数
                if (_read_callback)
                    _read_callback();
            }
            /*有可能会释放连接的操作事件，一次只处理一个
            if (_revents & EPOLLOUT)
            {
                if (_write_callback)
                    _write_callback();
            }
            else if (_revents & EPOLLERR)
            {
                if (_error_callback)
                    _error_callback(); // 一旦出错，就会释放连接，因此要放到前边调用任意回调
            }
            else if (_revents & EPOLLHUP)
            {
                if (_close_callback)
                    _close_callback();
            }
            /// 任何事件都调用该接口_event_callback
            if (_event_callback)
                _event_callback();
        }*/
        ~Channel()
        {
        }

    private:
        u_int32_t _events;  // 进行监控的事件
        u_int32_t _revents; // 本次监控触发的事件
        EventLoop *_loop;   // Channel对应的EventLoop
        int _sockfd;        // Channel对应的sockfd

        EventCallback _read_callback;  // 可读事件被触发的回调函数
        EventCallback _write_callback; // 可写事件被触发的回调函数
        EventCallback _error_callback; // 错误事件被触发的回调函数
        EventCallback _close_callback; // 连接断开事件被触发的回调函数
        EventCallback _event_callback; // 任意事件被触发的回调函数
    };
// 这是一个监控模块，对文件描述符进行事件监控
#define MAX_EPOLLEVENTS 1024
    class Poller
    {
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int, Channel *> _channels;

    private:
        // 对epoll的直接操作
        void Update(Channel *channel, int op)
        {
            // int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);
            int fd = channel->Fd();
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = channel->Events();
            int ret = epoll_ctl(_epfd, op, fd, &ev);
            if (ret < 0)
            {
                ERR_LOG("EPOLLCTL FAILED!");
            }
            return;
        }
        // 判断一个Channel是否已经添加了事件监控
        bool HasChannel(Channel *channel)
        {
            auto it = _channels.find(channel->Fd());
            if (it == _channels.end())
            {
                return false;
            }
            return true;
        }

    public:
        Poller()
        {
            _epfd = epoll_create(MAX_EPOLLEVENTS);
            if (_epfd < 0)
            {
                ERR_LOG("EPOLL CREATE FAILED!!");
                abort(); // 退出程序
            }
        }
        // 添加或修改监控事件
        void UpdateEvent(Channel *channel)
        {
            bool ret = HasChannel(channel);
            if (ret == false)
            {
                // 不存在则添加
                _channels.insert(std::make_pair(channel->Fd(), channel));
                return Update(channel, EPOLL_CTL_ADD);
            }
            return Update(channel, EPOLL_CTL_MOD);
        }
        // 移除监控
        void RemoveEvent(Channel *channel)
        {
            auto it = _channels.find(channel->Fd());
            if (it != _channels.end())
            {
                _channels.erase(it);
            }
            Update(channel, EPOLL_CTL_DEL);
        }
        // 开始监控，返回活跃连接
        void Poll(std::vector<Channel *> *active)
        {
            // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
            int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
            if (nfds < 0)
            {
                if (errno == EINTR)
                {
                    return;
                }
                ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
                abort(); // 退出程序
            }
            for (int i = 0; i < nfds; i++)
            {
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->setRevents(_evs[i].events); // 设置实际就绪的事件
                active->push_back(it->second);
            }
            return;
        }
    };

    using TaskFunc = std::function<void()>;
    using ReleaseFunc = std::function<void()>;
    class TimerTask
    {
    private:
        uint64_t _id;         // 定时器任务对象ID
        uint32_t _timeout;    // 定时任务的超时时间
        bool _canceled;       // false-表示没有被取消， true-表示被取消
        TaskFunc _task_cb;    // 定时器对象要执行的定时任务
        ReleaseFunc _release; // 用于删除TimerWheel中保存的定时器对象信息
    public:
        TimerTask(uint64_t id, uint32_t delay, const TaskFunc &cb) : _id(id), _timeout(delay), _task_cb(cb), _canceled(false) {}
        ~TimerTask()
        {
            if (_canceled == false)
                _task_cb(); // 用来取消定时任务，定时器中shared_ptr<TimerTask>副本，
            _release();     // 只有最后一个shared_ptr<TimerTask>对象析构时，才会调用~TimerTask()
        } // 从而执行_task_cb()，但是前提是定时任务没有被取消，如果取消了，则不会执行定时任务
        void Cancel() { _canceled = true; }
        void SetRelease(const ReleaseFunc &cb) { _release = cb; }
        uint32_t DelayTime() { return _timeout; }
    };

    class TimerWheel
    {
    private:
        using WeakTask = std::weak_ptr<TimerTask>;
        using PtrTask = std::shared_ptr<TimerTask>;
        int _tick;     // 当前的秒针，走到哪里释放哪里，释放哪里，就相当于执行哪里的任务
        int _capacity; // 表盘最大数量---其实就是最大延迟时间
        std::vector<std::vector<PtrTask>> _wheel;
        std::unordered_map<uint64_t, WeakTask> _timers;

        EventLoop *_loop;
        int _timerfd; // 定时器描述符--可读事件回调就是读取计数器，执行定时任务
        std::unique_ptr<Channel> _timer_channel;

    private:
        void RemoveTimer(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it != _timers.end())
            {
                _timers.erase(it);
            }
        }
        static int CreateTimerfd()
        {
            int timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
            if (timerfd < 0)
            {
                ERR_LOG("TIMERFD CREATE FAILED!");
                abort();
            }
            // int timerfd_settime(int fd, int flags, struct itimerspec *new, struct itimerspec *old);
            struct itimerspec itime;
            itime.it_value.tv_sec = 1;
            itime.it_value.tv_nsec = 0; // 第一次超时时间为1s后
            itime.it_interval.tv_sec = 1;
            itime.it_interval.tv_nsec = 0; // 第一次超时后，每次超时的间隔时
            timerfd_settime(timerfd, 0, &itime, NULL);
            return timerfd;
        }
        int ReadTimefd()
        {
            uint64_t times;
            // 有可能因为其他描述符的事件处理花费事件比较长，然后在处理定时器描述符事件的时候，有可能就已经超时了很多次
            // read读取到的数据times就是从上一次read之后超时的次数
            int ret = read(_timerfd, &times, 8);
            if (ret < 0)
            {
                ERR_LOG("READ TIMEFD FAILED!");
                abort();
            }
            return times;
        }
        // 这个函数应该每秒钟被执行一次，相当于秒针向后走了一步
        void RunTimerTask()
        {
            _tick = (_tick + 1) % _capacity;
            _wheel[_tick].clear(); // 清空指定位置的数组，就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
        }
        void OnTime()
        {
            // 根据实际超时的次数，执行对应的超时任务
            int times = ReadTimefd();
            for (int i = 0; i < times; i++)
            {
                RunTimerTask();
            }
        }
        void TimerAddInLoop(uint64_t id, uint32_t delay, const TaskFunc &cb)
        {
            PtrTask pt(new TimerTask(id, delay, cb));
            pt->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, id));
            int pos = (_tick + delay) % _capacity;
            _wheel[pos].push_back(pt);
            _timers[id] = WeakTask(pt);
        }
        void TimerRefreshInLoop(uint64_t id)
        {
            // 通过保存的定时器对象的weak_ptr构造一个shared_ptr出来，添加到轮子中
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return; // 没找着定时任务，没法刷新，没法延迟
            }
            PtrTask pt = it->second.lock(); // lock获取weak_ptr管理的对象对应的shared_ptr
            int delay = pt->DelayTime();
            int pos = (_tick + delay) % _capacity;
            _wheel[pos].push_back(pt);
        }
        void TimerCancelInLoop(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return; // 没找着定时任务，没法刷新，没法延迟
            }
            PtrTask pt = it->second.lock();
            if (pt)
                pt->Cancel();
        }

    public:
        TimerWheel(EventLoop *loop) : _capacity(60), _tick(0), _wheel(_capacity), _loop(loop),
                                      _timerfd(CreateTimerfd()), _timer_channel(new Channel(_loop, _timerfd))
        {
            _timer_channel->set_read_callback(std::bind(&TimerWheel::OnTime, this));
            _timer_channel->enAbleread(); // 启动读事件监控
        }
        /*定时器中有个_timers成员，定时器信息的操作有可能在多线程中进行，因此需要考虑线程安全问题*/
        /*如果不想加锁，那就把对定期的所有操作，都放到一个线程中进行*/
        void TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb);
        // 刷新/延迟定时任务
        void TimerRefresh(uint64_t id);
        void TimerCancel(uint64_t id);
        /*这个接口存在线程安全问题--这个接口实际上不能被外界使用者调用，只能在模块内，在对应的EventLoop线程内执行*/
        bool HasTimer(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return false;
            }
            return true;
        }
    };

    class EventLoop
    {
    public:
        /// @brief 初始化列表会按照成员变量在类中声明的顺序进行初始化
        using Funtor = std::function<void()>;
        EventLoop() : _eventfd(CreateEventFd()), _eventfd_channel(std::make_unique<Channel>(this, _eventfd)),
                      _timerWheel(this)
        {
            _eventfd_channel->set_read_callback(std::bind(&EventLoop::WeakUpEventFd, this));
            _eventfd_channel->enAbleread();
        }

        void Start()
        {
            // 1.进行事件监控
            std::vector<Channel *> actives;
            _poller.Poll(&actives);
            // 2.进行事件就绪处理
            for (auto channel : actives)
            {
                channel->HandleEvent();
            }
            // 3.执行任务
            RunAllTask();
        }

        void RunAllTask()
        {
            std::vector<Funtor> func;
            {
                std::unique_lock<std::mutex>(_mutex);
                func.swap(_tasks);
            }
            for (auto fuc : func)
            {
                fuc();
            }
            return;
        }

        /// @brief 移除事件监控
        /// @param channel
        void RemoveEvent(Channel *channel) { _poller.RemoveEvent(channel); }

        /// @brief 更新事件监控
        /// @param channel
        void UpdateEvent(Channel *channel) { _poller.UpdateEvent(channel); }

        bool isInloop() { return _thread_id == std::this_thread::get_id(); }

        void AssertInLoop() { assert(_thread_id == std::this_thread::get_id()); }

        void RunInLoop(const Funtor &cb)
        {
            /// 如果是EventLoop对应的线程,直接执行
            if (isInloop())
            {
                cb();
            }
            QueueInLoop(cb);
        }

        void QueueInLoop(const Funtor &cb)
        {
            {
                std::unique_lock<std::mutex> _lock(_mutex);
                _tasks.push_back(cb);
            }
        }
        /// @brief 不属于任何一个类对象，初始化对象的时候可以调用
        /// @return
        static int CreateEventFd()
        {
            int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
            if (efd < 0)
            {
                ERR_LOG("CREATE EVENTFD FAILED!!");
                abort(); // 让程序异常退出
            }
            return efd;
        }

        // 往eventfd中写入数据,唤醒当前线程
        void WeakUpEventFd()
        {
            u_int64_t data = 1;
            int n = eventfd_write(_eventfd, data);
            if (n <= 0)
            {
                if (errno == EINTR)
                {
                    ERR_LOG("WeakUpEventFd errno==EINTR");
                    return;
                }
                abort();
            }
            return;
        }

        /// @brief 目的就是让线程不要在epoll_wait处阻塞
        void ReadEventfd()
        {
            uint64_t val;
            int n = eventfd_read(_eventfd, &val);
            if (n < 0)
            {
                if (errno == EINTR || errno == EAGAIN)
                {
                    ERR_LOG("WeakUpEventFd errno==EINTR");
                    return;
                }
                abort();
            }
            return;
        }

        void TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb) { return _timerWheel.TimerAdd(id, delay, cb); }
        void TimerRefresh(uint64_t id) { return _timerWheel.TimerRefresh(id); }
        void TimerCancel(uint64_t id) { return _timerWheel.TimerCancel(id); }
        bool HasTimer(uint64_t id) { return _timerWheel.HasTimer(id); }

    private:
        std::thread::id _thread_id; // 线程ID,验证当前线程是否是该连接对应的EventLoop线程
        Poller _poller;             // 事件监控模块
        int _eventfd;               // eventfd用来通知
        std::unique_ptr<Channel> _eventfd_channel;
        std::vector<Funtor> _tasks;
        TimerWheel _timerWheel; // 定时器模块
        std::mutex _mutex;      // 任务队列的锁
    };

    void Channel::Remove() { return _loop->RemoveEvent(this); }
    void Channel::Update() { return _loop->UpdateEvent(this); }
    void TimerWheel::TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb)
    {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop, this, id, delay, cb));
    }
    // 刷新/延迟定时任务
    void TimerWheel::TimerRefresh(uint64_t id)
    {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop, this, id));
    }
    void TimerWheel::TimerCancel(uint64_t id)
    {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInLoop, this, id));
    }
}